package home.project.misc;

import home.project.Main;
import openfl.events.KeyboardEvent;
import haxe.io.Bytes;

/**
 * ...
 * @author an.vuongngocduy
 */

@:enum abstract KeyCode(Int) from Int to Int {
	var KEYCODE_BKSPACE 	= 0x0008;
	var KEYCODE_TAB 		= 0x0009;
	var KEYCODE_ENTER 		= 0x000D;
	var KEYCODE_SHIFT 		= 0x0010;
	var KEYCODE_CTRL 		= 0x0011;
	var KEYCODE_ALT 		= 0x0012;
	var KEYCODE_PAUSE		= 0x0013;
	var KEYCODE_CAPSLOCK 	= 0x0014;
	var KEYCODE_ESCAPE 		= 0x001B;
	var KEYCODE_SPACE 		= 0x0020;
	var KEYCODE_PAGEUP 		= 0x0021;
	var KEYCODE_PAGEDOWN 	= 0x0022;
	var KEYCODE_END 		= 0x0023;
	var KEYCODE_HOME 		= 0x0024;
	var KEYCODE_LEFT 		= 0x0025;
	var KEYCODE_UP 			= 0x0026;
	var KEYCODE_RIGHT 		= 0x0027;
	var KEYCODE_DOWN 		= 0x0028;
	var KEYCODE_INSERT 		= 0x002D;
	var KEYCODE_DELETE 		= 0x002E;
	var KEYCODE_A 			= 0x0041;
	var KEYCODE_B 			= 0x0042;
	var KEYCODE_C 			= 0x0043;
	var KEYCODE_D 			= 0x0044;
	var KEYCODE_E 			= 0x0045;
	var KEYCODE_F 			= 0x0046;
	var KEYCODE_G 			= 0x0047;
	var KEYCODE_H 			= 0x0048;
	var KEYCODE_I 			= 0x0049;
	var KEYCODE_J 			= 0x004A;
	var KEYCODE_K 			= 0x004B;
	var KEYCODE_L 			= 0x004C;
	var KEYCODE_M 			= 0x004D;
	var KEYCODE_N 			= 0x004E;
	var KEYCODE_O 			= 0x004F;
	var KEYCODE_P 			= 0x0050;
	var KEYCODE_Q 			= 0x0051;
	var KEYCODE_R 			= 0x0052;
	var KEYCODE_S 			= 0x0053;
	var KEYCODE_T 			= 0x0054;
	var KEYCODE_U 			= 0x0055;
	var KEYCODE_V 			= 0x0056;
	var KEYCODE_W 			= 0x0057;
	var KEYCODE_X 			= 0x0058;
	var KEYCODE_Y 			= 0x0059;
	var KEYCODE_Z 			= 0x005A;
	var KEYCODE_0			= 0x0030;
	var KEYCODE_1			= 0x0031;
	var KEYCODE_2			= 0x0032;
	var KEYCODE_3			= 0x0033;
	var KEYCODE_4			= 0x0034;
	var KEYCODE_5			= 0x0035;
	var KEYCODE_6			= 0x0036;
	var KEYCODE_7			= 0x0037;
	var KEYCODE_8			= 0x0038;
	var KEYCODE_9			= 0x0039;
	var KEYCODE_NUM_0		= 0x0060;
	var KEYCODE_NUM_1		= 0x0061;
	var KEYCODE_NUM_2		= 0x0062;
	var KEYCODE_NUM_3		= 0x0063;
	var KEYCODE_NUM_4		= 0x0064;
	var KEYCODE_NUM_5		= 0x0065;
	var KEYCODE_NUM_6		= 0x0066;
	var KEYCODE_NUM_7		= 0x0067;
	var KEYCODE_NUM_8		= 0x0068;
	var KEYCODE_NUM_9		= 0x0069;
	var KEYCODE_NUM_MUL		= 0x006A;
	var KEYCODE_NUM_ADD		= 0x006B;
	var KEYCODE_NUM_SUB		= 0x006D;
	var KEYCODE_NUM_DEC		= 0x006E;
	var KEYCODE_NUM_DIV		= 0x006F;	
	var KEYCODE_F1			= 0x0070;
	var KEYCODE_F2			= 0x0071;
	var KEYCODE_F3			= 0x0072;
	var KEYCODE_F4			= 0x0073;
	var KEYCODE_F5			= 0x0074;
	var KEYCODE_F6			= 0x0075;
	var KEYCODE_F7			= 0x0076;
	var KEYCODE_F8			= 0x0077;
	var KEYCODE_F9			= 0x0078;
	var KEYCODE_F10			= 0x0079;
	var KEYCODE_F11			= 0x007A;
	var KEYCODE_F12			= 0x007B;
	var KEYCODE_LSHIFT		= 0x00A0;
	var KEYCODE_RSHIFT		= 0x00A1;
	var KEYCODE_LCTRL		= 0x00A2;
	var KEYCODE_RCTRL		= 0x00A3;
	var KEYCODE_LALT		= 0x00A4;
	var KEYCODE_RALT		= 0x00A5;
	var KEYCODE_SEMICOLON	= 0x00BA;
	var KEYCODE_EQUAL		= 0x00BB;
	var KEYCODE_COMMA		= 0x00BC;
	var KEYCODE_MINUS		= 0x00BD;
	var KEYCODE_PERIOD		= 0x00BE;
	var KEYCODE_SLASH		= 0x00BF;
	var KEYCODE_GRAVE		= 0x00C0;
	var KEYCODE_LBRACKET	= 0x00DB;
	var KEYCODE_BKSLASH		= 0x00DC;
	var KEYCODE_RBRACKET 	= 0x00DD;
	var KEYCODE_QUOTE		= 0x00DE;	 
}

class KeyboardListener {
	public function new() {
		__previousKeys = Bytes.alloc(256);
		__previousKeys.fill(0, 256, 0);
		
		__currentKeys = Bytes.alloc(256);
		__currentKeys.fill(0, 256, 0);
	}
	
	public function keyPressed(p_keyCode:KeyCode):Bool {
		return (0x02 & __currentKeys.get(p_keyCode) != 0);
	}
	
	public function keyReleased(p_keyCode:KeyCode):Bool {
		return (0x01 & __currentKeys.get(p_keyCode) != 0);
	}
	
	public function update() {
		for (i in 0...__currentKeys.length) {
			__previousKeys.set(i, __currentKeys.get(i));
			__currentKeys.set(i , 0);
		}
	}
	
	@:allow(home.project.Main)
	private function __onKeyDown(p_event:KeyboardEvent):Void {
		switch(p_event.keyCode) {
			case KeyCode.KEYCODE_SHIFT:
				__currentKeys.set(Std.string(p_event.keyLocation) == "1" ? KeyCode.KEYCODE_LSHIFT : KeyCode.KEYCODE_RSHIFT, 0x02);
			case KeyCode.KEYCODE_CTRL:
				__currentKeys.set(Std.string(p_event.keyLocation) == "1" ? KeyCode.KEYCODE_LCTRL : KeyCode.KEYCODE_RCTRL, 0x02);
			case KeyCode.KEYCODE_ALT:
				__currentKeys.set(Std.string(p_event.keyLocation) == "1" ? KeyCode.KEYCODE_LALT : KeyCode.KEYCODE_RALT, 0x02);
			default:
				__currentKeys.set(p_event.keyCode, 0x02);
		}
	}
	
	@:allow(home.project.Main)
	private function __onKeyUp(p_event:KeyboardEvent):Void {
		switch(p_event.keyCode) {
			case KeyCode.KEYCODE_SHIFT:
				__currentKeys.set(Std.string(p_event.keyLocation) == "1" ? KeyCode.KEYCODE_LSHIFT : KeyCode.KEYCODE_RSHIFT, 0x01);
			case KeyCode.KEYCODE_CTRL:
				__currentKeys.set(Std.string(p_event.keyLocation) == "1" ? KeyCode.KEYCODE_LCTRL : KeyCode.KEYCODE_RCTRL, 0x01);
			case KeyCode.KEYCODE_ALT:
				__currentKeys.set(Std.string(p_event.keyLocation) == "1" ? KeyCode.KEYCODE_LALT : KeyCode.KEYCODE_RALT, 0x01);	
			default:
				__currentKeys.set(p_event.keyCode, 0x01);
		}
	}
	
	private var __currentKeys:Bytes;
	private var __previousKeys:Bytes;
}